//package org.web.projectStandardPlatform.client.helper;
//
//import com.sun.javadoc.ClassDoc;
//import com.sun.javadoc.FieldDoc;
//import com.sun.javadoc.MethodDoc;
//import com.sun.javadoc.RootDoc;
//import lombok.Getter;
//import lombok.Setter;
//import org.apache.commons.lang3.ObjectUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.context.properties.ConfigurationProperties;
//import org.springframework.util.ResourceUtils;
//import org.web.projectStandardPlatform.client.buildProject.domain.project.PropertiesDefinitionDO;
//
//import java.io.*;
//import java.lang.annotation.Annotation;
//import java.lang.reflect.Field;
//import java.lang.reflect.InvocationTargetException;
//import java.lang.reflect.Method;
//import java.nio.charset.StandardCharsets;
//import java.util.*;
//import java.util.List;
//
//
//import org.apache.poi.hssf.usermodel.HSSFWorkbook;
//import org.apache.poi.ss.usermodel.Cell;
//import org.apache.poi.ss.usermodel.Row;
//import org.apache.poi.ss.usermodel.Sheet;
//import org.apache.poi.ss.usermodel.Workbook;
//
//public class PropertiesParseHelper {
//
//    public static String SOURCE_PACKAGE = "src.main.java";
//
//    private static final List<String> ignoreMethodList = Arrays.asList("groups", "toString", "message", "equals", "annotationType", "hashCode", "payload", "hashCode");
//
//    private static final List<String> basePropertyTypeList = Arrays.asList("byte", "boolean", "short", "char", "int", "float", "long", "double");
//
//    private static final String BASE_PATH = new File("").getAbsolutePath() + File.separator + "target" + File.separator + "classes";
//
//    public static void parseConfig2Excel(String outPutFileName, List<String> scanPackage) throws Exception {
//        // 获取指定文件夹下，所有java类。
//
//        List<PropertiesDefinitionDO> list = parseJavaConfig2List(scanPackage);
//        buildExcelForProperties(outPutFileName, list);
//    }
//
//    private static JavaDoc parseComments(String javaSource) {
//        JavaDoc javaDoc = new JavaDoc();
//
//        try {
//            ArrayList<String> list = new ArrayList<>();
//            list.add("-doclet");
//            list.add(PropertiesParseHelper.class.getName());
//            list.add(javaSource);
//            com.sun.tools.javadoc.Main.execute(list.toArray(new String[list.size()]));
//            ClassDoc[] classes = PropertiesParseHelper.root.classes();
//            Map<String, FieldDoc> filedDocMap = new HashMap<>();
//            Map<String, MethodDoc> methodDocMap = new HashMap<>();
//            javaDoc.setFiledDocMap(filedDocMap);
//            javaDoc.setMethodDocMap(methodDocMap);
//            for (ClassDoc classDoc : classes) {
//                FieldDoc[] fields = classDoc.fields(false);
//                for (FieldDoc field : fields) {
//                    field.type().toString();
//                    filedDocMap.put(field.name(), field);
//                }
//                MethodDoc[] methods = classDoc.methods();
//                for (MethodDoc method : methods) {
//                    methodDocMap.put(method.name(), method);
//                }
//            }
//        } catch (Exception e) {
//            System.out.println(" aaaa " + javaSource);
//            e.printStackTrace();
//        }
//        return javaDoc;
//    }
//
//    @Setter
//    @Getter
//    static class JavaDoc {
//        private Map<String, FieldDoc> filedDocMap;
//        private Map<String, MethodDoc> methodDocMap;
//    }
//
//    /**
//     * 文档根节点
//     */
//    public static RootDoc root;
//
//    /**
//     * javadoc调用入口
//     *
//     * @param root
//     * @return
//     */
//    public static boolean start(RootDoc root) {
//        PropertiesParseHelper.root = root;
//        return true;
//    }
//
//    public static List<PropertiesDefinitionDO> buildDefaultExcelForProperties2(List<Class> clazzArray) throws Exception {
//
//        List<PropertiesDefinitionDO> propertiesDefinitionDOlist = new ArrayList<>();
//
//        for (Class<?> aClass : clazzArray) {
//            propertiesDefinitionDOlist.addAll(parsePropertiesDefinition(aClass));
//        }
//        return propertiesDefinitionDOlist;
//    }
//
//    public static void buildDefaultExcelForProperties(List<PropertiesDefinitionDO> propertiesDefinitionDOlist) throws Exception {
//        String basePath = ResourceUtils.getFile("").getAbsolutePath();
//        String fileName = basePath + File.separator + "target" + File.separator + "config.xls";
//        buildExcelForProperties(fileName, propertiesDefinitionDOlist);
//    }
//
//    public static void buildExcelForProperties(String fileName, List<PropertiesDefinitionDO> propertiesDefinitionDOlist) throws Exception {
//
//        FileOutputStream fileOutputStream = new FileOutputStream(fileName);
//        // 1、创建一个工作簿 03
//        Workbook workbook = new HSSFWorkbook();
//        // 2、创建一个工作表
//        Sheet sheet = workbook.createSheet("config");
//        // 3、创建一个行
//        Row firstRow = sheet.createRow(0);
//        // 4、创建一个单元格 (1,1)
//        Cell cell = firstRow.createCell(0);
//        cell.setCellValue("序号");
//        cell = firstRow.createCell(1);
//        cell.setCellValue("configuration_key");
//        cell = firstRow.createCell(2);
//        cell.setCellValue("default_value");
//        cell = firstRow.createCell(3);
//        cell.setCellValue("is_input_required");
//        cell = firstRow.createCell(4);
//        cell.setCellValue("function_type");
//        cell = firstRow.createCell(5);
//        cell.setCellValue("validation_rule_list");
//        cell = firstRow.createCell(6);
//        cell.setCellValue("configuration_comment");
//        cell = firstRow.createCell(7);
//        cell.setCellValue("input_time");
//        cell = firstRow.createCell(8);
//        cell.setCellValue("update_time");
//        cell = firstRow.createCell(9);
//        cell.setCellValue("reference_source");
//        cell = firstRow.createCell(10);
//        cell.setCellValue("configuration_type");
//
//        int i = 0;
//        for (PropertiesDefinitionDO propertiesDefinitionDO : propertiesDefinitionDOlist) {
//            Row row = sheet.createRow(i + 1);
//            // 4、创建一个单元格 (1,1)
//            Cell cell_0 = row.createCell(0);
//            cell_0.setCellValue(i + 1);
//            Cell cell_1 = row.createCell(1);
//            cell_1.setCellValue(propertiesDefinitionDO.getPropertyKey());
//            Cell cell_2 = row.createCell(2);
//            cell_2.setCellValue(propertiesDefinitionDO.getDefaultValue());
//            Cell cell_3 = row.createCell(3);
//            cell_3.setCellValue("");// 暂时不设置is_input_required，人工补充
//            Cell cell_4 = row.createCell(4);
//            cell_4.setCellValue("");// 暂时不设置function_type，人工补充
//            Cell cell_5 = row.createCell(5);
//            StringBuilder rules = new StringBuilder();
//            for (String str : propertiesDefinitionDO.getValidationRuleList()) {
//                rules.append(str).append("\n");
//            }
//            cell_5.setCellValue(StringUtils.removeEnd(rules.toString(), "\n"));
//            Cell cell_6 = row.createCell(6);
//            cell_6.setCellValue(propertiesDefinitionDO.getComments());
//
//            // Cell7, Cell8手动录入
//
//            Cell cell_9 = row.createCell(9);
//            cell_9.setCellValue(propertiesDefinitionDO.getReferenceSource());
//
//            Cell cell_10 = row.createCell(10);
//            cell_10.setCellValue(propertiesDefinitionDO.getPropertyType());
//
//            i++;
//            // 关闭流
//        }
//        workbook.write(fileOutputStream);
//        fileOutputStream.flush();
//        fileOutputStream.close();
//    }
//
//    @SafeVarargs
//    public static List<PropertiesDefinitionDO> parsePropertiesDefinition(Class<?>... clazzArray) throws InvocationTargetException, IllegalAccessException, ClassNotFoundException {
//        return parsePropertiesDefinition(null, clazzArray);
//    }
//
//    @SafeVarargs
//    public static List<PropertiesDefinitionDO> parsePropertiesDefinition(String parentPrefix, Class<?>... clazzArray) throws InvocationTargetException, IllegalAccessException, ClassNotFoundException {
//
//        List<PropertiesDefinitionDO> propertiesDefinitionDOList = new ArrayList<>();
//        if (clazzArray == null) {
//            return propertiesDefinitionDOList;
//        }
//
//        for (Class<?> clazz : clazzArray) {
//
//            boolean hasConfigurationProperties = false;
//
//            if (clazz.getDeclaredAnnotation(ConfigurationProperties.class) != null) {
//                hasConfigurationProperties = true; // 有没有ConfigurationProperties，解析方式不一样。
//            }
//
//            ConfigurationProperties configurationProperties = (ConfigurationProperties) clazz.getDeclaredAnnotation(ConfigurationProperties.class);
//            String prefixName = "";
//            if (configurationProperties != null) {
//                prefixName = configurationProperties.prefix();
//            }
//
//            Method[] methods = clazz.getDeclaredMethods();
//            for (int i = 0; i < methods.length; i++) {
//                // 这个写法不推荐
//                Method method = methods[i];
//                Annotation[][] annotations = method.getParameterAnnotations();
//                for (int j = 0; j < annotations.length; j++) {
//                    Annotation[] annotation = annotations[j];
//                    for (int k = 0; k < annotation.length; k++) {
//                        Annotation annotation1 = annotation[k];
//                        PropertiesDefinitionDO propertiesDefinitionDO = new PropertiesDefinitionDO();
//                        if (annotation1.annotationType() == Value.class) {
//                            Class paramClass = method.getParameterTypes()[j];
//                            Value valueAnnotation = (Value) annotation1;
//                            executeValueString(valueAnnotation.value().trim(), propertiesDefinitionDO);
//                            propertiesDefinitionDO.setPropertyType(paramClass.getName());
//                            propertiesDefinitionDO.setReferenceSource(clazz.getName() + "@" + method.getName());
//                            propertiesDefinitionDOList.add(propertiesDefinitionDO);
//                        }
//                    }
//                }
//            }
//
//            Field[] filds = clazz.getDeclaredFields();
//            //***********************
//            File file = new File("");
//            file.getAbsolutePath();
//            String str = file.getAbsolutePath() + File.separator + SOURCE_PACKAGE + File.separator + clazz.getName();
//            str = str.replace(".", File.separator) + ".java";
//            JavaDoc javaDoc = parseComments(str);
//            for (Field field : filds) {
////                ConfigComments configComments = field.getDeclaredAnnotation(ConfigComments.class);
////                if (ObjectUtils.isNotEmpty(configComments)) {
////                    propertiesDefinitionDO.setComments(configComments.value());
////                    if (BooleanUtils.isTrue(configComments.needInput())) {
////                        propertiesDefinitionDO.setNeedInput(true);
////                    }
////                }
//
//                // Value 注解优先级高于ConfigurationProperties
//                Value configValue = field.getDeclaredAnnotation(Value.class);
//                if (!hasConfigurationProperties && configValue == null) {
//                    continue;
//                }
//
//                PropertiesDefinitionDO propertiesDefinitionDO = new PropertiesDefinitionDO();
//
//                if (javaDoc != null && javaDoc.getFiledDocMap().get(field.getName()) != null) {
//                    FieldDoc fieldDoc = javaDoc.getFiledDocMap().get(field.getName());
//                    propertiesDefinitionDO.setComments(fieldDoc.commentText());
//                }
//                propertiesDefinitionDO.setReferenceSource(clazz.getName());
//                propertiesDefinitionDOList.add(propertiesDefinitionDO);
//                propertiesDefinitionDO.setPropertyType(field.getType().getName());
//                if (ObjectUtils.isNotEmpty(configValue) && (StringUtils.isNotBlank(configValue.value()))) {
//                    executeValueString(configValue.value().trim(), propertiesDefinitionDO);
//                    String value = configValue.value().trim().replace("${", "").replace("}", "").replace(",,", ",");
//                    String[] array = value.split(":");
//                    if (array.length >= 2) {
//                        propertiesDefinitionDO.setPropertyKey(array[0]);
//                        propertiesDefinitionDO.setDefaultValue(array[1]);
//                    } else {
//                        propertiesDefinitionDO.setPropertyKey(array[0]);
//                    }
//                } else {
//                    // 属性上的ConfigurationProperties 高于类声明的ConfigurationProperties。
//                    ConfigurationProperties methodConfigurationProperties = field.getDeclaredAnnotation(ConfigurationProperties.class);
//                    if (methodConfigurationProperties != null) {
//                        propertiesDefinitionDO.setPropertyKey(methodConfigurationProperties.prefix() + "." + field.getName());
//                    } else {
//                        if (StringUtils.isEmpty(prefixName) && StringUtils.isNotBlank(parentPrefix)) {
//                            prefixName = parentPrefix;
//                        }
//                        propertiesDefinitionDO.setPropertyKey(prefixName + "." + field.getName());
//                    }
//                }
//
//                Annotation[] annotations = field.getAnnotations();
//                for (Annotation annotation : annotations) {
//                    Class<? extends Annotation> aClass = annotation.annotationType();
//                    if (aClass.getName().startsWith("jakarta.validation.constraints") || aClass.getName().startsWith("org.hibernate.validator.constraints")) {
//                        Method[] annotationMethodArray = annotation.getClass().getDeclaredMethods();
//                        StringBuilder stringBuffer = new StringBuilder(annotation.annotationType().getSimpleName() + "(");
//
//                        Map<String, String> map = new HashMap<>();
//                        for (Method method : annotationMethodArray) {
//                            if (!ignoreMethodList.contains(method.getName())) {
//                                map.put(method.getName(), method.invoke(annotation).toString());
//                            }
//                        }
//                        int loop = 0;
//                        for (Map.Entry<String, String> entry : map.entrySet()) {
//                            loop++;
//                            String mapKey = entry.getKey();
//                            String mapValue = entry.getValue();
//                            if (loop == map.size()) {
//                                stringBuffer.append(mapKey).append("=").append(mapValue);
//                            } else {
//                                stringBuffer.append(mapKey).append("=").append(mapValue).append(",");
//                            }
//                        }
//                        propertiesDefinitionDO.getValidationRuleList().add(stringBuffer.append(")").toString());
//                    }
//                }
//
//                // 递归调用，如果类型是对象类，非基础类型，非基础类型包装类类型，则需要递归处理。递归只建议一层，多层递归，非人脑所能及。
//                if (!basePropertyTypeList.contains(propertiesDefinitionDO.getPropertyType()) && (!StringUtils.startsWith(propertiesDefinitionDO.getPropertyType(), "java.lang"))) {
//                    propertiesDefinitionDOList.addAll(parsePropertiesDefinition(propertiesDefinitionDO.getPropertyKey(), Class.forName(propertiesDefinitionDO.getPropertyType())));
//                }
//            }
//        }
//
//        return propertiesDefinitionDOList;
//    }
//
//    private static void executeValueString(String value, PropertiesDefinitionDO propertiesDefinitionDO) {
//        String executeValue = value.trim().replace("${", "").replace("}", "").replace(",,", ",");
//        String[] array = executeValue.split(":");
//        if (array.length >= 2) {
//            propertiesDefinitionDO.setPropertyKey(array[0]);
//            propertiesDefinitionDO.setDefaultValue(array[1]);
//        } else {
//            propertiesDefinitionDO.setPropertyKey(array[0]);
//        }
//    }
//
//    public static void executeFile(List<String> directoryList, List<String> fileList, String folderName, Boolean onlyCurrent) {
//        File file = new File(folderName);
//        if (file.exists()) {
//            if (file.isFile()) {
//                fileList.add(file.getAbsolutePath());
//            } else if (file.isDirectory()) {
//                directoryList.add(file.getAbsolutePath());
//                String[] list = file.list();
//                int fileNum = file.list().length;
//                for (int i = 0; i < fileNum; i++) {
//                    File tempFile = new File(file.getAbsolutePath() + File.separator + list[i]);
//                    if (tempFile.isFile()) {
//                        fileList.add(tempFile.getAbsolutePath());
//                    } else if (!onlyCurrent) {
//                        executeFile(directoryList, fileList, tempFile.getAbsolutePath(), false);
//                    } else {
//                        directoryList.add(tempFile.getAbsolutePath());
//                    }
//                }
//            }
//        }
//    }
//
//    public static void mergePropertiesAndConfigJava(String out, List<String> ignorePropertiesFileList, List<String> scanPackage) throws Exception {
//        List<String> propertiesFileList = parsePropertiesFile(null, ignorePropertiesFileList);
//        Map<String, PropertiesDefinitionDO> mapForProperties = parseMap(propertiesFileList);
//        List<PropertiesDefinitionDO> list = parseJavaConfig2List(scanPackage);
//        List<String> keyList = new ArrayList<>();
//        for (PropertiesDefinitionDO propertiesDefinitionDO : list) {
//            keyList.add(propertiesDefinitionDO.getPropertyKey());
//        }
//        for (String key : mapForProperties.keySet()) {
//            if (!keyList.contains(key)) {
//                list.add(mapForProperties.get(key));
//            }
//        }
//        buildExcelForProperties(out, list);
//    }
//
//    public static List<PropertiesDefinitionDO> parseJavaConfig2List(List<String> scanPackage) throws Exception {
//        List<String> allJavaFile = new ArrayList<>();
//        File file = new File("");
//        String basePath = file.getAbsoluteFile() + File.separator + "target" + File.separator + "classes";
//        for (String packageName : scanPackage) {
//            packageName = basePath + File.separator + packageName.replace(".", File.separator);
//            allJavaFile.addAll(getAllFile(packageName));
//        }
//        // 去掉非.class文件
//        List<String> allClassFile = new ArrayList<>();
//        for (String javaClass : allJavaFile) {
//            File classFile = new File(javaClass);
//            if (classFile.getName().endsWith(".class")) {
//                allClassFile.add(javaClass);
//            }
//        }
//        List<Class> allJavaClass = new ArrayList<>();
//        for (String javaClass : allClassFile) {
//            try {
//                //把javaClass转成class
//                String pattern = "target" + File.separator + "classes" + File.separator;
//                String classPattern = ".class";
//                String fileClassName = javaClass.substring(javaClass.indexOf(pattern) + pattern.length()).replace(File.separator, ".");
//                fileClassName = fileClassName.substring(0, fileClassName.length() - classPattern.length());
//                Class<?> clazz = Class.forName(fileClassName);
//                allJavaClass.add(clazz);
//            } catch (ClassNotFoundException e) {
//                e.printStackTrace();
//            }
//        }
//        List<PropertiesDefinitionDO> list = buildDefaultExcelForProperties2(allJavaClass);
//        return list;
//    }
//
//    public static List<String> parsePropertiesFile(String scanPropertiesPackage, List<String> ignorePropertiesFileList) {
//        File file = new File("");
//        if (StringUtils.isEmpty(scanPropertiesPackage)) {
//            scanPropertiesPackage = file.getAbsolutePath() + File.separator + "target" + File.separator + "classes";
//        } else {
//            scanPropertiesPackage = BASE_PATH + File.separator + scanPropertiesPackage.replace(".", File.separator);
//        }
//        List<String> list = getAllFile(scanPropertiesPackage);
//        List<String> filterList = new ArrayList<>();
//        for (String str : list) {
//            File file1 = new File(str);
//            String fileName = file1.getName();
//            if ((fileName.endsWith(".properties"))) {
//                if (!(ignorePropertiesFileList != null && ignorePropertiesFileList.contains(fileName))) {
//                    filterList.add(str);
//                }
//            }
//        }
//        return filterList;
//    }
//
//
//    public static List<String> getAllFile(String folderName) {
//        List<String> directoryList = new ArrayList<>();
//        List<String> fileList = new ArrayList<>();
//        executeFile(directoryList, fileList, folderName, false);
//        return fileList;
//    }
//
//    public static List<String> convertFileToList(InputStream is) throws Exception {
//        List<String> list = new ArrayList<>();
//        BufferedReader in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
//        String line = "";
//        while ((line = in.readLine()) != null) {
//            if (StringUtils.isNotBlank(line)) {
//                list.add(line);
//            }
//        }
//        in.close();
//        return list;
//    }
//
//    public static Map<String, PropertiesDefinitionDO> parseMap(List<String> propertiesFileList) throws Exception {
//
//        List<String> lineList = new ArrayList<>();
//        for (String propertiesFile : propertiesFileList) {
//            lineList.addAll(convertFileToList(new FileInputStream(new File(propertiesFile))));
//        }
//
//        Map<String, PropertiesDefinitionDO> propertiesDefinitionMapByPropertyKey = new HashMap<>();
//        StringBuilder lastComments = new StringBuilder();
//        for (String line : lineList) {
//            if (line.trim().startsWith("#")) { // 处理注释
//                if (StringUtils.isNotBlank(lastComments)) {
//                    lastComments.append("\n").append(line);
//                } else {
//                    lastComments.append(line.trim().replaceFirst("#", ""));
//                }
//            } else {
//                int firstLength = line.indexOf("=");
//                String keyName = line.substring(0, firstLength);
//                PropertiesDefinitionDO propertiesDefinitionDO = new PropertiesDefinitionDO();
//                propertiesDefinitionDO.setPropertyKey(keyName);
//                if (propertiesDefinitionMapByPropertyKey.get(keyName) != null) {
//                    System.out.println(keyName + " 有重复。");
//                }
//                propertiesDefinitionMapByPropertyKey.put(propertiesDefinitionDO.getPropertyKey(), propertiesDefinitionDO);
//                String value = line.substring(firstLength).trim().replaceFirst("=", "");
//                propertiesDefinitionDO.setReferenceSource("property");
//                if (StringUtils.isNumeric(value)) {
//                    propertiesDefinitionDO.setPropertyType("int");
//                } else {
//                    propertiesDefinitionDO.setPropertyType("java.lang.String");
//                }
//                propertiesDefinitionDO.setComments(lastComments.toString());
//                lastComments = new StringBuilder();
//            }
//        }
//        return propertiesDefinitionMapByPropertyKey;
//    }
//
//}
